<script setup lang="ts">
import { ref, onMounted, nextTick, watchEffect } from "vue"
import BotResponse from '../component/BotResponse.vue'
import UserResponse from '../component/UserResponse.vue'
import { fetchSteamPost } from "../utils/fetchStream"
import { getChatHistory, resetChat } from "../api/chat"
import { Howl } from 'howler';
import { useMessage, NButton, NIcon, NPopconfirm } from "naive-ui"
import { SendSharp, RefreshCircle } from '@vicons/ionicons5'
type Role = 'user' | 'assistant'
interface Message {
    role: Role;
    content: string;
    audioPath?: string;
}
const message = useMessage()
// robotMessage AI 临时存储的对话
const robotMessage = ref('')

// userMessage 存储用户临时的输入
const userMessage = ref('')

// 存储临时的语音
let tmpAudioPath = ref('')
const isResponse = ref(false)
watchEffect(() => {
    if (tmpAudioPath.value) {
        const sound = new Howl({
            src: [`/api/${tmpAudioPath.value}`],
            html5: true,
            onend: function () {
                isResponse.value = false
            },
            onloaderror:function(){
                isResponse.value = false
            }
        });
        sound.play();
    }
})

const messageList = ref<Message[]>([])
const handleScrollBottom = () => {
    const contentContainer = document.querySelector('.content')
    if (contentContainer) {
        contentContainer.scrollTo({
            top: contentContainer.scrollHeight,
            behavior: "smooth"
        })
    }
}

// resetChatHistory 清空聊天重新测评
const resetChatHistory = async () => {
    const res = await resetChat()
    if (res.code == 200) {
        initChatHistory()
    }
}
const onSendKeyUp = (e: KeyboardEvent) => {
    e.preventDefault()
    e.stopPropagation()
    if (e.keyCode == 13) {
        sendMessage()
    }
}
const sendMessage = () => {
    if (isResponse.value) {
        message.warning('姐姐正在讲话喔，不要打断先!')
        return
    }
    if (userMessage.value.trim().length > 0) {
        messageList.value.push({
            role: 'user',
            content: userMessage.value
        })
        callChat(userMessage.value)
        userMessage.value = ""
        nextTick(() => {
            handleScrollBottom()
        })
    }
}
// 开始读取数据流
const callChat = async (promote = '您好') => {
    fetchSteamPost('/api/chat/bdv2', {
        promote: promote,
        model: "ernie-lite-8k"
    })
        // 处理响应
        .then(response => {
            isResponse.value = true
            if (!response.ok) {
                throw new Error('Network response was not ok');
                isResponse.value = false
            }
            // 获取响应体的流
            const stream = response.body;
            let isDone = false
            if (stream) {
                // 通过流获取读取器
                const reader = stream.getReader();
                const decoder = new TextDecoder('utf-8');
                const readStream = async () => {
                    const { value, done } = await reader.read();
                    if (done) {
                        return;
                    }
                    const chunk = decoder.decode(value, { stream: true });
                    // 处理 SSE 数据块，假设数据以 'data:' 开头
                    const lines = chunk.split('\n');
                    nextTick(() => {
                        handleScrollBottom()
                    })
                    lines.forEach(line => {
                        if (line.indexOf('[AUDIO]') != -1) {
                            // 音频文件
                            const audioDataUrl = line.replace('[AUDIO]', '').trim();
                            const audioUrlObject = audioDataUrl.substring('data:'.length).trim();
                            console.log('audioUrlObject', JSON.parse(audioUrlObject))
                            tmpAudioPath.value = JSON.parse(audioUrlObject).audioPath
                            return
                        }
                        if (line.indexOf('[DONE]') != -1 || line.indexOf('end') != -1 || line.indexOf('end') != -1 || line.indexOf('data: {}') != -1) {
                            if (!isDone) {
                                messageList.value.push({
                                    role: 'assistant',
                                    content: robotMessage.value,
                                    audioPath: tmpAudioPath.value
                                })
                                robotMessage.value = ""
                            }
                            isDone = true
                            return
                        }
                        if (line.startsWith('data:') && line.length > 5) {
                            const dataPart = line.substring('data:'.length).trim();
                            try {
                                const reasoning_content = dataPart
                                robotMessage.value += reasoning_content ? reasoning_content : ''
                                // 这里可以进一步处理接收到的数据，比如更新 UI 等
                            } catch (error) {
                                console.log('Error parsing data:', line, error);
                            }
                        }
                    });
                    await readStream();
                }
                readStream()
            }
        })

        // 捕获任何错误
        .catch(error => {
            console.error('Error:', error);
        });
}

const initChatHistory = async () => {
    messageList.value = []
    const res = await getChatHistory()
    if (res.data.length) {
        messageList.value = res.data
        nextTick(() => {
            handleScrollBottom()
        })
    } else {
        callChat()
    }
}
onMounted(() => {
    initChatHistory()
})
</script>

<template>
    <div class="AssessmentChat pb-32 p-12 md:w-2/3 m-auto">
        <div v-for="item in messageList" class="m-2">
            <!-- 渲染 messageList content -->
            <BotResponse v-if="item.role === 'assistant'" :robotMessage="item.content" />
            <UserResponse v-else :userMessage="item.content" />
            <!-- <audio :src="item.audioPath" controls /> -->
        </div>
        <div v-if="robotMessage.length > 0">
            <BotResponse :robotMessage="robotMessage" />
        </div>

        <div class="fixed bottom-0 left-0 right-0 bg-white/70 backdrop-blur-sm border-t border-gray-100">
            <div class="max-w-3xl mx-auto px-4 py-4">
                <div class="flex items-end space-x-3">
                    <!-- 语音输入切换 -->
                    <!-- <button class="mb-2 p-2 hover:bg-gray-100 rounded-full transition">
                        <img src="https://unpkg.com/lucide-static@latest/icons/mic.svg" class="w-6 h-6 text-gray-600">
                    </button> -->

                    <!-- 多行输入框 -->
                    <div class="flex-1 relative">
                        <textarea @keyup="onSendKeyUp" v-model="userMessage"
                            :placeholder="isResponse ? '' : '请输入消息...后回车'"
                            class="flex-1 bg-white/80 backdrop-blur-sm rounded-2xl p-4 pr-12 resize-none focus:outline-none transition-all duration-500 text-xs overflow-hidden"
                            :class="isResponse ? 'w-0' : 'w-full shadow-xl '" rows="1"
                            style="scrollbar-width: none;"></textarea>

                        <!-- 发送按钮 -->
                        <div class="absolute  bottom-3 right-3 p-2 hover:bg-gray-100 rounded-full transition">
                            <n-popconfirm positive-text="确定" negative-text="取消" @positive-click="resetChatHistory"
                                class="mr-10">
                                确定要清空当前聊天记录，重新开始测评吗
                                <template #trigger>
                                    <n-button v-show="!isResponse" round :loading="isResponse" color="#f00"
                                        @click="sendMessage">
                                        重新测评
                                        <template #icon>
                                            <n-icon>
                                                <RefreshCircle v-show='!isResponse' />
                                            </n-icon>
                                        </template>
                                    </n-button>
                                </template>
                            </n-popconfirm>
                            <n-button round :loading="isResponse" color="#8a2be2" :class="isResponse ? 'w-full' : ''"
                                @click="sendMessage">
                                {{ isResponse ? '姐姐正在回复你呢!' : '发送' }}
                                <template #icon>
                                    <n-icon>
                                        <SendSharp v-show='!isResponse' />
                                    </n-icon>
                                </template>
                            </n-button>

                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<style scoped>
.about {
    text-align: center;
    padding: 2rem;
}
</style>